#pragma once

namespace idl
{

 #ifdef WIN32
  /******************************************BEGIN WINDOWS IMPLEMENTATION**********************************/
  #ifndef WIN32_LEAN_AND_MEAN
  #define WIN32_LEAN_AND_MEAN
  #endif

  #include <windows.h>

  class i_thread
  {
    friend DWORD WINAPI ThreadProc(LPVOID lpParam); /*a friend function of the WINAPI class*/
  public:
    i_thread();
    ~i_thread();
    bool start(void(*thread_func)(void*), void *data);
    void wait();
  private:
    void(*m_thread_func)(void*);
    void *m_data;
    DWORD m_id;
    HANDLE m_handle;
    void run();
  };

  class i_critical
  {
  public:
    i_critical();
    ~i_critical();
    void enter();
    void leave();
  private:
    CRITICAL_SECTION m_cs;
  };

  class i_event
  {
  public:
    i_event();
    ~i_event();
    void set();
    void unset();
    void wait();
  private:
    HANDLE m_ev;
  };
  /******************************************END OF WINDOWS IMPLEMENTATION**********************************/

 #else
  
  /******************************************BEGIN EMPTY IMPLEMENTATION**********************************/
  class i_thread
  {
  public:
    i_thread(){}
    ~i_thread(){}
    void start(void(*thread_func)(void*), void *user_data){}
    void wait(){}
  };

  class i_critical
  {
  public:
    i_critical(){}
    ~i_critical(){}
    void enter(){}
    void leave(){}
  };

  class i_event
  {
  public:
    i_event(){}
    ~i_event(){}
    void set(){}
    void unset(){}
    void wait(){}
  };

  /******************************************END OF EMPTY IMPLEMENTATION**********************************/

#endif

} /*namespace idl*/
